package com.hexingmo.dawn.lang;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

/**
 * 数据存储单位枚举类
 * <p>
 * 提供了计算机存储中常用的数据单位定义和转换功能，支持以下单位：
 * <ul>
 *   <li><strong>BIT (b)</strong> - 比特，最小的数据单位</li>
 *   <li><strong>BYTE (B)</strong> - 字节，1字节 = 8比特</li>
 *   <li><strong>KILOBYTE (KB)</strong> - 千字节，1KB = 1024字节</li>
 *   <li><strong>MEGABYTE (MB)</strong> - 兆字节，1MB = 1024KB</li>
 *   <li><strong>GIGABYTE (GB)</strong> - 千兆字节，1GB = 1024MB</li>
 *   <li><strong>TERABYTE (TB)</strong> - 太字节，1TB = 1024GB</li>
 *   <li><strong>PETABYTE (PB)</strong> - 拍字节，1PB = 1024TB</li>
 *   <li><strong>EXABYTE (EB)</strong> - 艾字节，1EB = 1024PB</li>
 *   <li><strong>ZETTABYTE (ZB)</strong> - 泽字节，1ZB = 1024EB</li>
 *   <li><strong>YOTTABYTE (YB)</strong> - 尧字节，1YB = 1024ZB</li>
 * </ul>
 * </p>
 *
 * <h3>主要功能：</h3>
 * <ul>
 *   <li><strong>单位转换</strong> - 支持任意两个存储单位之间的转换</li>
 *   <li><strong>精度控制</strong> - 可以指定转换结果的小数位数</li>
 *   <li><strong>舍入模式</strong> - 支持多种舍入模式（HALF_UP、DOWN、UP等）</li>
 *   <li><strong>格式化输出</strong> - 提供智能格式化功能，自动调整小数位数</li>
 * </ul>
 *
 * <h3>使用示例：</h3>
 * <pre>{@code
 * // 基本转换
 * BigDecimal bytes = DataUnit.KILOBYTE.toByte(BigDecimal.ONE, 2);
 * BigDecimal bits = DataUnit.MEGABYTE.toBit(new BigDecimal("1.5"), 3);
 *
 * // 使用自定义舍入模式
 * BigDecimal result = DataUnit.BYTE.toKiloByte(
 *     new BigDecimal("1024"), 2, RoundingMode.DOWN);
 *
 * // 转换到指定单位
 * BigDecimal gb = DataUnit.MEGABYTE.convertTo(
 *     new BigDecimal("1536"), DataUnit.GIGABYTE, 3, RoundingMode.UP);
 *
 * // 大单位转换
 * BigDecimal pb = DataUnit.TERABYTE.toPetaByte(new BigDecimal("1024"), 2);
 * BigDecimal eb = DataUnit.PETABYTE.toExaByte(new BigDecimal("1024"), 2);
 *
 * // 格式化输出
 * String formatted = DataUnit.GIGABYTE.format(new BigDecimal("2.567"));
 * // 输出: "2.57 GB"
 * }</pre>
 *
 * <h3>注意事项：</h3>
 * <ul>
 *   <li>所有转换都基于二进制单位（1024进制），而非十进制（1000进制）</li>
 *   <li>默认使用 {@link RoundingMode#HALF_UP} 舍入模式</li>
 *   <li>格式化功能会根据数值大小自动调整小数位数</li>
 *   <li>支持高精度计算，使用 {@link BigDecimal} 避免浮点数精度问题</li>
 *   <li>大单位（PB、EB、ZB、YB）主要用于理论计算和未来存储容量规划</li>
 *   <li>使用 {@link BigInteger} 存储比特数，支持超大数值计算</li>
 * </ul>
 *
 * <h3>性能考虑：</h3>
 * <ul>
 *   <li>枚举值在类加载时初始化，转换系数已预计算</li>
 *   <li>适合频繁的单位转换场景</li>
 *   <li>内存占用较小，每个枚举实例只存储必要的转换系数</li>
 * </ul>
 *
 * @author He Xing Mo
 * @since 1.0
 */
public enum DataUnit {

    /**
     * 比特
     */
    BIT("b") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8), scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8L * 1024L), scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_2), scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_3), scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_4), scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_5), scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_6), scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_7), scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BigDecimal.valueOf(8).multiply(BASE_POW_8), scale, roundingMode);
        }
    },

    /**
     * 字节
     */
    BYTE("B") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_3, scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_4, scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_5, scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_6, scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_7, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_8, scale, roundingMode);
        }
    },

    /**
     * 千字节
     */
    KILOBYTE("KB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8).multiply(BASE)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_3, scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_4, scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_5, scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_6, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_7, scale, roundingMode);
        }
    },

    /**
     * 兆字节
     */
    MEGABYTE("MB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8).multiply(BASE_POW_2)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_3, scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_4, scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_5, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_6, scale, roundingMode);
        }
    },

    /**
     * 千兆字节
     */
    GIGABYTE("GB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8).multiply(BASE_POW_3)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_3).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_3, scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_4, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_5, scale, roundingMode);
        }
    },

    /**
     * 太字节
     */
    TERABYTE("TB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8).multiply(BASE_POW_4)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_4).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_3).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_3, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_4, scale, roundingMode);
        }
    },

    /**
     * 拍字节
     */
    PETABYTE("PB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8).multiply(BASE_POW_5)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_5).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_4).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_3).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_3, scale, roundingMode);
        }
    },

    /**
     * 艾字节
     */
    EXABYTE("EB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BigDecimal.valueOf(8).multiply(BASE_POW_6)).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_6).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_5).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_4).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_3).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE_POW_2, scale, roundingMode);
        }
    },

    /**
     * 泽字节
     */
    ZETTABYTE("ZB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            BigDecimal multiplier = BigDecimal.valueOf(8).multiply(BASE_POW_7);
            return value.multiply(multiplier).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_7).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_6).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_5).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_4).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_3).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.divide(BASE, scale, roundingMode);
        }
    },

    /**
     * 尧字节
     */
    YOTTABYTE("YB") {
        @Override
        public BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode) {
            BigDecimal multiplier = BigDecimal.valueOf(8).multiply(BASE_POW_8);
            return value.multiply(multiplier).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_8).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_7).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_6).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_5).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_4).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_3).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE_POW_2).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.multiply(BASE).setScale(scale, roundingMode);
        }

        @Override
        public BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode) {
            return value.setScale(scale, roundingMode);
        }
    };

    /**
     * 1024
     */
    private static final BigDecimal BASE = BigDecimal.valueOf(1024);

    /**
     * 1024^2
     */
    private static final BigDecimal BASE_POW_2 = BASE.pow(2);

    /**
     * 1024^3
     */
    private static final BigDecimal BASE_POW_3 = BASE.pow(3);

    /**
     * 1024^4
     */
    private static final BigDecimal BASE_POW_4 = BASE.pow(4);

    /**
     * 1024^5
     */
    private static final BigDecimal BASE_POW_5 = BASE.pow(5);

    /**
     * 1024^6
     */
    private static final BigDecimal BASE_POW_6 = BASE.pow(6);

    /**
     * 1024^7
     */
    private static final BigDecimal BASE_POW_7 = BASE.pow(7);

    /**
     * 1024^8
     */
    private static final BigDecimal BASE_POW_8 = BASE.pow(8);

    private final String symbol;

    DataUnit(String symbol) {
        this.symbol = symbol;
    }

    public String getSymbol() { return symbol; }

    /**
     * 将当前单位的值转换为比特
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的比特值
     */
    public abstract BigDecimal toBit(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的字节值
     */
    public abstract BigDecimal toByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为千字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的千字节值
     */
    public abstract BigDecimal toKiloByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为兆字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的兆字节值
     */
    public abstract BigDecimal toMegaByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为千兆字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的千兆字节值
     */
    public abstract BigDecimal toGigaByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为太字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的太字节值
     */
    public abstract BigDecimal toTeraByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为拍字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的拍字节值
     */
    public abstract BigDecimal toPetaByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为艾字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的艾字节值
     */
    public abstract BigDecimal toExaByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为泽字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的泽字节值
     */
    public abstract BigDecimal toZettaByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为尧字节
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的尧字节值
     */
    public abstract BigDecimal toYottaByte(BigDecimal value, int scale, RoundingMode roundingMode);

    /**
     * 将当前单位的值转换为比特（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的比特值
     */
    public BigDecimal toBit(BigDecimal value, int scale) {
        return toBit(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的字节值
     */
    public BigDecimal toByte(BigDecimal value, int scale) {
        return toByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为千字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的千字节值
     */
    public BigDecimal toKiloByte(BigDecimal value, int scale) {
        return toKiloByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为兆字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的兆字节值
     */
    public BigDecimal toMegaByte(BigDecimal value, int scale) {
        return toMegaByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为千兆字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的千兆字节值
     */
    public BigDecimal toGigaByte(BigDecimal value, int scale) {
        return toGigaByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为太字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的太字节值
     */
    public BigDecimal toTeraByte(BigDecimal value, int scale) {
        return toTeraByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为拍字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的拍字节值
     */
    public BigDecimal toPetaByte(BigDecimal value, int scale) {
        return toPetaByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为艾字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的艾字节值
     */
    public BigDecimal toExaByte(BigDecimal value, int scale) {
        return toExaByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为泽字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的泽字节值
     */
    public BigDecimal toZettaByte(BigDecimal value, int scale) {
        return toZettaByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为尧字节（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param scale 精度（小数位数）
     * @return 转换后的尧字节值
     */
    public BigDecimal toYottaByte(BigDecimal value, int scale) {
        return toYottaByte(value, scale, RoundingMode.HALF_UP);
    }

    /**
     * 将当前单位的值转换为指定单位
     *
     * @param value 要转换的值
     * @param targetUnit 目标单位
     * @param scale 精度（小数位数）
     * @param roundingMode 舍入模式
     * @return 转换后的值
     */
    public BigDecimal convertTo(BigDecimal value, DataUnit targetUnit, int scale, RoundingMode roundingMode) {
        if (targetUnit == null) {
            throw new IllegalArgumentException("Target unit cannot be null");
        }

        switch (targetUnit) {
            case BIT:
                return toBit(value, scale, roundingMode);
            case BYTE:
                return toByte(value, scale, roundingMode);
            case KILOBYTE:
                return toKiloByte(value, scale, roundingMode);
            case MEGABYTE:
                return toMegaByte(value, scale, roundingMode);
            case GIGABYTE:
                return toGigaByte(value, scale, roundingMode);
            case TERABYTE:
                return toTeraByte(value, scale, roundingMode);
            case PETABYTE:
                return toPetaByte(value, scale, roundingMode);
            case EXABYTE:
                return toExaByte(value, scale, roundingMode);
            case ZETTABYTE:
                return toZettaByte(value, scale, roundingMode);
            case YOTTABYTE:
                return toYottaByte(value, scale, roundingMode);
            default:
                throw new IllegalArgumentException("Unknown target unit: " + targetUnit);
        }
    }

    /**
     * 将当前单位的值转换为指定单位（使用默认舍入模式HALF_UP）
     *
     * @param value 要转换的值
     * @param targetUnit 目标单位
     * @param scale 精度（小数位数）
     * @return 转换后的值
     */
    public BigDecimal convertTo(BigDecimal value, DataUnit targetUnit, int scale) {
        return convertTo(value, targetUnit, scale, RoundingMode.HALF_UP);
    }

    /**
     * 格式化数值和单位
     *
     * @param value 数值
     * @param roundingMode 舍入模式
     * @return 格式化字符串
     */
    public String format(BigDecimal value, RoundingMode roundingMode) {
        if (value == null) {
            return "0 " + symbol;
        }

        // 根据数值大小调整精度
        int scale;
        if (value.compareTo(BigDecimal.valueOf(100)) >= 0) {
            // 大于等于100时，不显示小数
            scale = 0;
        } else if (value.compareTo(BigDecimal.valueOf(10)) >= 0) {
            // 大于等于10时，显示1位小数
            scale = 1;
        } else {
            // 小于10时，显示2位小数
            scale = 2;
        }

        BigDecimal roundedValue = value.setScale(scale, roundingMode);
        return roundedValue + " " + symbol;
    }

    /**
     * 格式化数值和单位（使用默认舍入模式HALF_UP）
     *
     * @param value 数值
     * @return 格式化字符串
     */
    public String format(BigDecimal value) {
        return format(value, RoundingMode.HALF_UP);
    }
}
